package com.jichaoyun.util.ChatUtils;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jichaoyun.config.WebSocketConfig;
import com.jichaoyun.dao.mapper.ScheduelRealtimeMapper;
import com.jichaoyun.model.entity.ScheduelRealtime;
//import com.jichaoyun.model.entity.ScheduelRealtimeMapper;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

@ServerEndpoint(value = "/websocket/{user}",configurator= WebSocketConfig.class)
@Component
@Slf4j
public class MyWebSocket {

    //用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
    //用来记录username和该session进行绑定
    private static Map<Integer, Session> map = new HashMap<Integer, Session>();
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    //用户名
    private Integer userId;
    //获取全局容器
    private ApplicationContext applicationContext;
    //聊天逻辑service
    @Resource
    private ScheduelRealtimeMapper mapper;

    /**
     * 连接建立成功调用的方法，初始化昵称、session
     */
    @OnOpen
    public void onOpen(@PathParam(value = "user") Integer param, Session session, EndpointConfig config) {
        //获取登录时存放httpSession的用户数据
        HttpSession httpSession= (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(httpSession.getServletContext());

        Integer userId = param;
        log.info(userId+"站点上线了");
        this.applicationContext = applicationContext;
        this.session = session;
        this.userId = userId;
        this.mapper = (ScheduelRealtimeMapper) applicationContext.getBean("scheduelRealtimeMapper");

        //绑定userId与session
        map.put(userId, session);

        webSocketSet.add(this);     //加入set中

    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {

        //todo 断开连接，重置窗口值
        webSocketSet.remove(this);  //从set中删除

    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message) {

        //从客户端传过来的数据是json数据，所以这里使用jackson进行转换为chatMsg对象，
        ObjectMapper objectMapper = new ObjectMapper();
        ScheduelRealtime scheduelRealtime;
        try {
            scheduelRealtime = objectMapper.readValue(message, ScheduelRealtime.class);
            //对chatMsg进行装箱
            scheduelRealtime.setSendId(userId);
            Session fromSession = map.get(scheduelRealtime.getSendId());
            Session toSession = map.get(scheduelRealtime.getReceiveId());
            //发送给接收者.
            fromSession.getAsyncRemote().sendText(userId + "：" + scheduelRealtime.getContent());
            if (toSession != null) {
                //发送给发送者.
                toSession.getAsyncRemote().sendText(userId + "：" + scheduelRealtime.getContent());
            }
            //保存聊天记录信息
            scheduelRealtime.setIsRead(false);
            scheduelRealtime.setCreateTime(new Date());
            mapper.insert(scheduelRealtime);

        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
